import { app, Menu, Tray, ipcMain, dialog, desktopCapturer, screen } from 'electron';
import { asset, protocolName, getProtocolUrl, sleep } from '../util';
import downloader, { downloadOptions } from './download';
import appinfo from '../appinfo';
import { createDrawWindow } from '../window/drawWindow';
import { createMainWindow } from '../window/mainWindow';
import { createAiWindow, minimizeAiToBall, maximizeAiToPanel } from '../window/aiWindow';
// 修复部分客户端https提示证书不正确
process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';

// 对当前主机进行注册/写入协议
app.setAsDefaultProtocolClient(protocolName);

app.allowRendererProcessReuse = true;
app.commandLine.appendSwitch('ignore-certificate-errors');

const gotTheLock = app.requestSingleInstanceLock();
// 主窗口
export let mainWindow;
// 授课画笔窗口
let sidebarWindow;
// 保存授课窗口得穿透状态
let aiWindow;

if (!gotTheLock) {
  app.quit();
} else {
  let tray = null;
  const iconPath = asset('icon.ico');

  const sendToRenderer = (...args) => {
    if (mainWindow) {
      mainWindow.webContents.send(...args);
    }
  };

  // 对当前启动参数进行判断处理（app.isPackaged用来区分开发阶段及包阶段）
  const handleArgv = (argv) => {
    if (app.isReady()) {
      const url = getProtocolUrl(argv);
      if (url) sendToRenderer('clientProtocol', url);
    }
  };

  /**
   * 创建系统图标
   */
  const createTray = () => {
    if (!tray || tray.isDestroyed()) {
      tray = new Tray(iconPath);
      tray.setToolTip(appinfo.name);
      tray.on('click', () => {
        if (mainWindow) {
          if (!mainWindow.isVisible()) {
            mainWindow.show();
          } else if (mainWindow.isMinimized()) {
            mainWindow.restore();
          } else {
            mainWindow.hide();
          }
        }
      });
      tray.on('right-click', () => {
        if (mainWindow && mainWindow.isMinimized()) {
          mainWindow.restore();
        }
      });
    }
    const contextMenu = Menu.buildFromTemplate([
      {
        label: '打开应用',
        click: () => {
          if (mainWindow) {
            if (!mainWindow.isVisible()) {
              mainWindow.show();
            } else if (mainWindow.isMinimized()) {
              mainWindow.restore();
            }
          }
        },
      },
      {
        label: '刷新应用',
        click: () => {
          sendToRenderer('reload');
        },
      },
      {
        type: 'separator',
      },
      {
        label: '退出',
        click: () => {
          app.quit();
        },
      },
    ]);
    tray.setContextMenu(contextMenu);
  };

  /**
   * 创建窗口
   */
  const createWindow = () => {
    // 创建主窗口
    mainWindow = createMainWindow();
    // 下载功能测试
    downloader(mainWindow, sendToRenderer);

    // 通过 IPC 通信，在主窗口中控制侧边栏的显示与隐藏
    ipcMain.on('show-win', () => {
      if (mainWindow.isVisible()) {
        mainWindow.hide();
      } else {
        mainWindow.show();
      }
    });

    // 创建教辅工具窗口
    // type = bar 从客户端侧边栏打开
    // type = resource 直接从资源打开的
    ipcMain.on('create-draw-windows', async () => {
      sidebarWindow = createDrawWindow();
      // 使用 setFullScreen(true)：这会使窗口全屏并且通常会隐藏任务栏。
      // 使用 setKiosk(true)：这将使窗口进入一个更严格的全屏模式，在此模式下任务栏和其他界面元素将被隐藏。
      sidebarWindow.setKiosk(true);
      await sleep(1500);
      mainWindow.setKiosk(true);
    });

    // 销毁教辅工具窗口
    ipcMain.on('destory-draw-windows', () => {
      console.log('销毁教辅工具');
      // 退回到打开教辅工具之前的路由里
      sendToRenderer('clientOpenPage', 'quit');
      createDrawWindow('destroy', async () => {
        sidebarWindow = null;
        mainWindow.setFullScreen(false);
      });
    });

    // 创建openai窗口
    ipcMain.on('open-ai-panel', async (e, keysJson) => {
      if (!aiWindow) {
        // console.log('keysJson =====> ', keysJson);
        // 窗口AI窗口前，先从mainWindow中的 <webview> 中获取 token 令牌信息
        // const keysJson = JSON.stringify(['token', r('userId'), r('drawType')]);
        const data = await getLocalStorageValues(keysJson);
        // 创建的时候 需要token，否则会导致窗口内的程序跳转到登录页面
        aiWindow = createAiWindow(null, null, data, mainWindow);
      } else {
        // 如果窗口已经创建, 且再次点击了创建窗口，那么就展开
        aiWindow.webContents.send('ai-pack-up');
      }
    });

    // 进入授课模式
    ipcMain.on('open-teaching-mode', () => {
      // 全屏
      mainWindow.maximize();
    });

    // 授课模式页面销毁 或者 退出
    ipcMain.on('teaching-quit', () => {
      // 通知教辅工具面板
      if (sidebarWindow) {
        sidebarWindow.webContents.send('watch-teaching-quit');
      }
    });

    // 最小化openai窗口（变成圆圈显示在桌面上）
    ipcMain.on('open-ai-minimization', () => {
      minimizeAiToBall();
    });

    // 最大化openai窗口（最大化）
    ipcMain.on('open-ai-maximize', () => {
      maximizeAiToPanel();
    });

    // 关闭openai窗口
    ipcMain.on('open-ai-close', () => {
      createAiWindow('destroy', () => {
        // 成功销毁后的回调执行
        aiWindow = null;
      });
    });

    // 处理draw传参key 来进行iframe中的一些系统操作：iframe内push等
    ipcMain.on('watch-send-key', (event, keyName) => {
      // 最大化
      mainWindow.maximize();
      switch (keyName) {
        // 教材
        case 'textbook':
          // 操作指令为: push 到
          sendToRenderer('clientOpenPage', 'push:clientTeachingMaterial');
          break;
        // 教参
        case 'church':
          sendToRenderer('clientOpenPage', 'push:clientTeachingStaff');
          break;
        // 返回上一层
        case 'back':
          sendToRenderer('clientOpenPage', 'back');
          break;
        // 关闭 授课 模式
        case 'quit':
          sendToRenderer('clientQuit');
          break;
      }
    });

    // 计算
    ipcMain.on('main-windows-touch', (e, options) => {
      // 否则判断
      // 1. 如果点击的是切换画布，且当前状态是禁止穿透ignoreStataus=false时,修改为允许穿透
      // 2. 如果是其他情况，直接设置为禁止穿透
      if (sidebarWindow) {
        // console.log('options =====> ', options);
        sidebarWindow.webContents.send('message-to-renderer', options);
      }
    });

    // 鼠标效果穿透,默认画笔蒙版常在,所以需要设置穿透,否则将无法点击主窗口
    ipcMain.on('mouse-across', (event, bool, options) => {
      // 使用 dialog 模块显示消息框
      sidebarWindow.setIgnoreMouseEvents(bool, options);
    });

    // 处理渲染进程发送的 invoke 请求
    ipcMain.handle('capture-page', async () => {
      let width, height;
      try {
        // 截取页面内容
        // 获取客户端base64数据
        let webContents;
        let imageBuffer;
        let imageDataURL;
        // 如果主客户端被隐藏或者不是最大化，就截图桌面
        // 如果主客户端存在，就截图客户端
        // console.log('主客户端是否最大化 =====> ', mainWindow.isMaximized());
        if (mainWindow.isMaximized()) {
          const screens = screen.getPrimaryDisplay().workAreaSize;
          console.log('screens ==================> ', screens);
          width = screens.width;
          height = screens.height;
          webContents = mainWindow.webContents;
          imageBuffer = await webContents.capturePage();
          imageDataURL = imageBuffer.toDataURL();
        } else {
          // mainWindow 不可见时，截取屏幕的内容
          const primaryDisplay = screen.getPrimaryDisplay();
          // const { width: screenWidth, height: screenHeight } = primaryDisplay.size;
          const preScreen = primaryDisplay.size;
          width = preScreen.width;
          height = preScreen.height;
          // 设置弹窗高度，铺满全屏高度
          sidebarWindow.setBounds({ width, height });
          // 截取屏幕
          const sources = await desktopCapturer.getSources({
            types: ['screen'],
            thumbnailSize: { width, height }, // 设置截图的大小为减去任务栏后的屏幕高度
          });

          // 获取到的第一个源就是整个屏幕的源
          const targetSource = sources[0];
          imageBuffer = targetSource.thumbnail.toPNG();

          // 将截图转换为 base64 数据
          imageDataURL = `data:image/png;base64,${imageBuffer.toString('base64')}`;
        }
        return { size: { width, height }, img: imageDataURL };
        // return { size: imageBuffer.getSize(), img: imageDataURL };
      } catch (error) {
        console.error('Error capturing page:', error);
        return { error: error.message };
      }
    });

    // 处理渲染进程传递的授课资源列表
    ipcMain.on('set-course-resource', (e, data) => {
      // 传递数据给窗口
      if (sidebarWindow) {
        sidebarWindow.webContents.send('set-course', data);
      }
    });

    // 客户端内切换资源 传递给渲染进程
    ipcMain.on('resource-change', (e, data) => {
      sendToRenderer('resourceChange', data);
    });

    // inType = resource 时,需要主动去获取资源,否则异步会导致资源加载失败
    ipcMain.on('get-source-data', (e, data) => {
      sendToRenderer('getSourceData', data);
    });

    // 接受websocket order 命令
    ipcMain.on('callws-order', (e, data) => {
      sendToRenderer('callwsOrder', data);
    });

    // 客户端接受 websocket 文件传输
    ipcMain.on('callws-files', (e, data) => {
      sendToRenderer('callwsFiles', data);
    });

    // 获取主窗口webview的data
    ipcMain.handle('get-page-data', async (e, keysJson) => {
      try {
        const localsJson = await getLocalStorageValues(keysJson);
        const task = getTaskSystem();
        // 存放taskId
        localsJson.taskHeight = task;
        return localsJson;
      } catch (error) {
        // console.log('error ===> ', error);
      }
    });
  };

  ipcMain.on('downloadOptions', (e, cid, url, options) => {
    downloadOptions(url, options)
      .catch((error) => ({ error }))
      .then(() => {
        sendToRenderer('downloadOptions', cid, url);
      });
  });

  ipcMain.on('showOpenDialog', (e, props) => {
    dialog.showOpenDialog(mainWindow, props, (...args) => {
      sendToRenderer('showOpenDialog', ...args);
    });
  });

  // app.disableHardwareAcceleration();
  // This method will be called when Electron has finished
  // initialization and is ready to create browser windows.
  // Some APIs can only be used after this event occurs.
  app.on('ready', () => {
    createWindow();
    createTray();
  });

  app.on('second-instance', (event, argv) => {
    if (process.platform === 'win32') {
      handleArgv(argv);
    }
    // Someone tried to run a second instance, we should focus our window.
    if (mainWindow) {
      if (!mainWindow.isVisible()) {
        mainWindow.show();
      } else if (mainWindow.isMinimized()) {
        mainWindow.restore();
      }
      mainWindow.focus();
    }
  });
  // Quit when all windows are closed.
  app.on('window-all-closed', function () {
    // On macOS it is common for applications and their menu bar
    // to stay active until the user quits explicitly with Cmd + Q
    if (process.platform !== 'darwin') {
      app.quit();
    }
  });

  app.on('activate', function () {
    // On macOS it's common to re-create a window in the app when the
    // dock icon is clicked and there are no other windows open.
    if (mainWindow === null) {
      createWindow();
    }
  });

  // 捕获未捕获的异常
  process.on('uncaughtException', (error) => {
    const errorMessage = `An uncaught exception occurred: ${error.stack}`;
    dialog.showErrorBox('Error', errorMessage);
  });
}

// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.

// 获取指定键的 sessionStorage 值
async function getLocalStorageValues(keysJson) {
  try {
    const localsJson = await mainWindow.webContents.executeJavaScript(`
      document.querySelector('webview').executeJavaScript(\`
        try {
          const result = ${keysJson}.reduce((acc, key) => {
            acc[key] = sessionStorage.getItem(key) || localStorage.getItem(key);
            return acc;
          }, {});
          JSON.stringify(result);
        } catch (e) {
          console.error('Error in webview script:', e);
          throw e;
        }
      \`)
    `);

    return JSON.parse(localsJson);
  } catch (error) {
    console.error('Error executing script in webview:', error);
    throw error;
  }
}

function getTaskSystem() {
  // 获取主屏幕的工作区域和大小
  const primaryDisplay = screen.getPrimaryDisplay();
  const screenHeight = primaryDisplay.size.height;
  const workAreaHeight = primaryDisplay.workAreaSize.height;

  // 任务栏高度 = 屏幕高度 - 工作区域高度
  const taskbarHeight = screenHeight - workAreaHeight;
  return taskbarHeight;
}
